﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Bill.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using System.ComponentModel;

namespace Zy.K3Cloud.ToolbarCreateFactoryNumber
{
    /// <summary>
    /// 【表单插件】点击生成出厂编码
    /// </summary>
    [Description("【表单插件】点击生成出厂编码"), HotUpdate]
    public class ToolbarListPlugIn : AbstractDynamicFormPlugIn
    {
        /// <summary>
        /// 将数值的字符串数组按区间分段
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        private static string CompareNumber(string[] arr)
        {
            int[] arr2 = new int[arr.Length];
            bool isZero = arr[0][0] == '0';
            for (int i = 0; i < arr.Length; i++)
            {
                arr2[i] = Convert.ToInt32(arr[i]);
            }

            var query = arr2.OrderBy(p => p).Aggregate<int, List<List<int>>>(null, (m, n) =>
            {
                if (m == null) return new List<List<int>>() { new List<int>() { n } };
                if (m.Last().Last() != n - 1)
                {
                    m.Add(new List<int>() { n });
                }
                else
                {
                    m.Last().Add(n);
                }
                return m;
            });
            //打印结果
            string rs = "";

            query.ForEach(p => rs = (p.First() == p.Last()) ? (isZero ? "0" : "") + p.First() : ((isZero ? "0" : "") + p.First() + (isZero ? "-0" : "-") + p.Last())); 
            return rs;
        }

        /// <summary>
        /// 检查出厂编码与销售数量容量是否相符
        /// </summary>
        /// <returns>>0：销售数量减小；<0：销售数量增多; =0：销售没变或编码为空</returns>
        private static int CheckCount(DynamicObject entityObj)
        {
            string fn = entityObj["F_HY_Text1"] != null ? entityObj["F_HY_Text1"].ToString() : ""; //出厂编码字段
            int count = Convert.ToInt32(entityObj["Qty"]); //销售数量
            int fn_count;
            if (fn != "")
            {
                String[] fns = fn.Split('-');
                if (fns.Length == 1)
                {
                    fn_count = 1;
                }
                else if (fns.Length == 2)
                {
                    fn_count = Convert.ToInt32(fns[1]) - Convert.ToInt32(fns[0]) + 1;
                }
                else
                {
                    //编码有多个-符号，此种情况按不相符处理
                    fn_count = -999;
                }

                return fn_count - count; //编码容量与销售数量不相符则提示需要更新条码；
            }else
            {
                return 0;
            }
        }

        /// <summary>
        /// 分录中手工点击创建出厂编码
        /// </summary>
        /// <param name="e"></param>
        public override void BarItemClick(BarItemClickEventArgs e)
        {
            base.BarItemClick(e);
            if (e.BarItemKey.Equals("ora_CreateFactoryNumber", StringComparison.OrdinalIgnoreCase))
            {
                var entity = this.View.BillBusinessInfo.GetEntity("FSaleOrderEntry");
                var entityObjs = this.View.Model.GetEntityDataObject(entity);
                if (entityObjs != null)
                {
                    int index = 0;
                    String skipped = ""; //保存被跳过编码的行号
                    String coded = ""; //保存被编码的行号

                    foreach (var entityObj in entityObjs)
                    {
                        //遍历单据体数据包
                        //按行生成出厂编码
                        //设置单据体的当前行
                        this.Model.SetEntryCurrentRowIndex("FSaleOrderEntry", index);

                        string ruleId = ""; //存储编码规则内码
                        string fntype = entityObj["F_ora_fn_type"] != null ? entityObj["F_ora_fn_type"].ToString() : "";
                        int count = Convert.ToInt32(entityObj["Qty"]); //销售数量
                        var Material = (DynamicObject)entityObj["MaterialId"];//物料对象

                        if (count == 0 || Material == null)
                        {
                            skipped = (skipped == "") ? Convert.ToString(index) : skipped + "," + Convert.ToString(index);
                            break; //销售数量为0或没填物料编码的跳过。
                        }

                        string materialId = Material["Number"].ToString();//物料编码
                        string fntxt = entityObj["F_HY_Text1"]!= null ? entityObj["F_HY_Text1"].ToString() : ""; //出厂编码字段
                        string materialName = Material["Name"].ToString(); //名称

                        //获取单据体元数据
                        EntryEntity entry = this.View.BillBusinessInfo.GetEntryEntity("FSaleOrderEntry");
                        //获取指定一行的单据体数据
                        DynamicObject entity_obj = this.Model.GetEntityDataObject(entry, index);
                        //获取子单据体元数据
                        SubEntryEntity sub_entry = this.View.BillBusinessInfo.GetEntryEntity("F_ora_SubEntity") as SubEntryEntity;
                        //出厂编码子单据体的总行数
                        int subRowCounts = this.Model.GetEntryRowCount("F_ora_SubEntity");

                        if (fntype == "")
                        {
                            //this.View.ShowErrMessage(string.Format("第 {0} 行未选择物料类别！", Convert.ToString(index+1)), "物料类别错误");
                            //return;
                            coded = (coded == "") ? Convert.ToString(index) : coded + "," + Convert.ToString(index);
                            break; //物料编码没填的行跳过。
                        }

                        bool executeReCode = true;
                        if( fntxt != "" )
                        {
                            int compareResult = CheckCount(entityObj);
                            if (compareResult > 0){
                                //编码容量比销售量大，销售数量减小；
                                //从分录中减少编码，从最大的开始；
                                //减小编码范围
                                //删除编号表中多余的行
                                if (subRowCounts > count)
                                {
                                    for (int KK = count; KK < subRowCounts; KK++)
                                    {
                                        this.Model.DeleteEntryRow("F_ora_SubEntity", KK); //key为单据体标识
                                    }
                                    this.View.UpdateView("F_ora_SubEntity");
                                }
                                String[] rfn = new string[count];
                                for (int rk = 0; rk < count; rk++)
                                {
                                    rfn[rk] = this.View.Model.GetValue("F_ora_sub_Fn", rk).ToString();
                                }
                                this.Model.SetItemValueByID("F_HY_Text1", CompareNumber(rfn), index);
                                executeReCode = false; //调整编码范围完成，无需重新生成；
                                coded = (coded == "") ? Convert.ToString(index) : coded + "," + Convert.ToString(index);
                            }
                            else if(compareResult < 0)
                            {
                                //编码容量比销售量小，销售数量变大，需全部重新生成新码;
                                executeReCode = true;
                            }
                            else
                            {
                                //编码容量与销售量相符，询问是否生成编码；
                                //this.View.ShowMessage(string.Format("第 {0} 行 {1} 的出厂编码已存在，并且编码数与销售数量也相符，需要重新生成新编码么？", Convert.ToString(index + 1), materialModel), MessageBoxOptions.YesNo, result =>
                                //{
                                //    executeReCode = result == MessageBoxResult.Yes;
                                //});
                                skipped = (skipped == "") ? Convert.ToString(index) : skipped + "," + Convert.ToString(index);
                                executeReCode = false ; //编码存在，无需重新生成的跳过
                            }
                        }

                        if (executeReCode == false)
                        {
                            index++;
                            continue;
                        }
                        switch (fntype)
                        {
                            ///SELECT a.FRULEID AS 编码规则内码,b.FNAME AS 编码规则名称,a.* FROM T_BAS_BILLCODERULE a LEFT JOIN T_BAS_BILLCODERULE_L b ON a.FRULEID=b.FRULEID AND b.FLOCALEID=2052 WHERE a.FBILLFORMID='SAL_SaleOrder' AND b.FNAME='采购订单编码规则AH'
                            case "1": //YT
                                ruleId = "625d1a1da043ac";
                                break;
                            case "2": //CD
                                ruleId = "625d1a58a043ca";
                                break;
                            case "3": //调节板
                                ruleId = "625d1a6ea043ed";
                                break;
                            case "4": //特殊
                                ruleId = "625d1a7ea04430";
                                break;
                            default:
                                ruleId = "557561cf8ca005";
                                break;
                        }

                        var field = this.View.BillBusinessInfo.GetField("F_HY_Text1");//出厂编码

                        string[] fn = new string[count];


                        //删除编号表中多余的行
                        if( subRowCounts > count)
                        {
                            for (int KK = count; KK < subRowCounts; KK++)
                            {
                                this.Model.DeleteEntryRow("F_ora_SubEntity", KK); //key为单据体标识
                            }
                            this.View.UpdateView("F_ora_SubEntity");
                        }

                        for (int i = 0; i < count; i++)
                        {
                            var factoryNumber = BusinessDataServiceHelper.GetBillNoByField(this.Context, this.View.BillBusinessInfo, new[] { this.Model.DataObject }, true, ruleId, field, null);
                            if (factoryNumber != null && factoryNumber.Count > 0)
                            {
                                fn[i] = factoryNumber[0].BillNo; 
                                //创建新的子单据体分录行
                                this.Model.CreateNewEntryRow(entity_obj, sub_entry, -1);
                                
                                //子单据体行赋值用
                                this.View.Model.SetValue("F_ora_sub_Fn", fn[i], i);
                                this.View.Model.SetValue("F_ora_FnMemo", "", i);
                             //   this.View.Model.SetValue("F_ora_Text", fn[i], i);
                             //   this.View.Model.SetValue("F_ora_Text1", "", i);
                                this.View.Model.SetValue("FBILLNO", ""); //获取编码后要清空表单编号字段，便于下次获取。
                                this.View.UpdateView("F_ora_SubEntity");
                            }
                        }
                        this.Model.SetItemValueByID("F_HY_Text1", CompareNumber(fn), index);
                        index++;
                    }
                    this.View.ShowMessage(string.Format("成功生成出厂编码的行号为：{0}; 因未选编码类别、未填销售数量、未填物料编码或已存在无需调整跳过的行号为：{1}", coded, skipped), MessageBoxOptions.OK);
                }
            }
        }
    }
}
